#include "ipcInterface.h"

static void* ip_camera_init_real(const char *ip, const int port, const char *url, const char *user, const char *passwd, \
    const IPCameraRecvCallBackFunc callBack, void *context, const unsigned int channelIndex);
static int departUrl(const char *url, char *ip, int *port, char *realUrl);
static void addDefaultPort(char *url);

void* ip_camera_init(const char *url, const char *user, const char *passwd, const IPCameraRecvCallBackFunc callBack, void* context, const unsigned int channelIndex)
{
	char ip[64];
	int port;
	char realUrl[256];

	memset(ip, 0, sizeof(ip));
	port = 0;
	memset(realUrl, 0, sizeof(realUrl));

	char url2[256];
	strcpy(url2, url);
	addDefaultPort(url2);
	departUrl(url2, ip, &port, realUrl);
	return ip_camera_init_real(ip, port, realUrl, user, passwd, callBack, context, channelIndex);
}

static void addDefaultPort(char *url)
{
	char addString[] = ":554";
	//int addStringLen = strlen(addString);
	char tmpUrl[256];
	strcpy(tmpUrl, url);
	char *ipStart = strstr(tmpUrl, "//");
	if (!ipStart)
	{
		udi_erro_log("%s:can not find // in url ! url = %s\n", __FUNCTION__, url);
		return;
	}

	ipStart += 2;
	char *ipStop = strstr(ipStart, ":");
	if (!ipStop)
	{
		char *tail = strstr(ipStart, "/");
		char tmpTail[256];
		strcpy(tmpTail, tail);
		memset(tail, 0, 150 * sizeof(char));
		snprintf(url, 256, "%s%s%s", tmpUrl, addString, tmpTail);
		udi_info_log("rebuild rtsp url is %s\n", url);
	}
}

static int departUrl(const char *url, char *ip, int *port, char *realUrl)
{
	char tmpUrl[256];
	strcpy(tmpUrl, url);
	char *ipStart = strstr(tmpUrl, "//");
	if (!ipStart)
	{
		udi_erro_log("%s:can not find // in url ! url = %s\n", __FUNCTION__, url);
		return -1;
	}

	ipStart += 2;
	char *ipStop = strstr(ipStart, ":");
	if (!ipStop)
	{
		udi_erro_log("%s:can not find : in url ! url = %s\n", __FUNCTION__, url);
		return -2;
	}

	*ipStop = '\0';
	strcpy(ip, ipStart);
	*ipStop = ':';

	char *portStart = ipStop + 1;
	char *portStop = strstr(portStart, "/");
	if (!portStop)
	{
		udi_erro_log("%s:can not find / in url when finding port ! url = %s\n", __FUNCTION__, url);
		return -3;
	}

	*portStop = '\0';
	*port = atoi(portStart);
	*portStop = '/';

	char *urlStart = portStop;
	strcpy(realUrl, urlStart);
	
	return 0;
}

static void* ip_camera_init_real(const char *ip, const int port, const char *url, const char *user, const char *passwd, \
    const IPCameraRecvCallBackFunc callBack, void* context, const unsigned int channelIndex)
{
	//udi_info_log("+%s\n", __FUNCTION__);
	if (!url || !ip || port <= 0 || !callBack || !user || !passwd)
	{
		udi_erro_log("%s: para error ! %p,%p,%d,%p,%p\n", __FUNCTION__, url, ip, port, user, passwd);
		return NULL;
	}
	//udi_info_log("%s para,  %s:%d, %s, %s, %s", __FUNCTION__, ip, port, url, user, passwd);

	CameraInfo *pCameraInfo = (CameraInfo *)malloc(sizeof(CameraInfo));
	if (pCameraInfo == NULL)
	{
		udi_erro_log("%s:malloc pCameraInfo fail !\n", __FUNCTION__);
		return NULL;
	}
	memset(pCameraInfo, 0, sizeof(CameraInfo));

	Camera *pCamera = &(pCameraInfo->camera);
	strcpy(pCamera->cUrl, url);
	strcpy(pCamera->cIp, ip);
	pCamera->iPort = port;
	strcpy(pCamera->cUsr, user);
	strcpy(pCamera->cPassWd, passwd);

	pCameraInfo->pCallBack = callBack;
	pCameraInfo->context = context;
	pCameraInfo->channelndex = channelIndex;

	pCameraInfo->is_start = 1;
	int ret = initCamera(pCameraInfo);
	if (ret < 0)
	{
		pCameraInfo->is_start = 0;
		return NULL;
	}

	return (void *)pCameraInfo;
}

int ip_camera_exit(void *ipCameraObj)
{
	udi_info_log("+%s\n", __FUNCTION__);

	if (ipCameraObj == NULL)
	{
		udi_erro_log("%s:para error ! ipCameraObj=%p\n", __FUNCTION__, ipCameraObj);
		return -1;
	}

	CameraInfo *pCameraInfo = (CameraInfo*)ipCameraObj;

	pCameraInfo->is_start = 0;
	if(pCameraInfo->connect_thread_id > 0)
	{
		pthread_join(pCameraInfo->connect_thread_id, NULL);
		pCameraInfo->connect_thread_id = 0;
	}
	if(pCameraInfo->deal_thread_id > 0)
	{
		pthread_join(pCameraInfo->deal_thread_id, NULL);
		pCameraInfo->connect_thread_id = 0;
	}

	free(pCameraInfo);

	return 0;
}

int ip_camera_add_frameidx(void *ipCameraObj)
{
	if (ipCameraObj == NULL)
	{
		udi_erro_log("%s:ipCameraObj is NULL !\n", __FUNCTION__);
		return -1;
	}

	CameraInfo *pCameraInfo = (CameraInfo *)ipCameraObj;
	pCameraInfo->frameIndex++;

	return 0;
}

unsigned int ip_camera_get_frameidx(void *ipCameraObj)
{
	if (ipCameraObj == NULL)
	{
		udi_erro_log("%s:ipCameraObj is NULL !\n", __FUNCTION__);
		return -1;
	}

	CameraInfo *pCameraInfo = (CameraInfo *)ipCameraObj;
	return pCameraInfo->frameIndex;
}


int ip_camera_get_connect_status(void *ipCameraObj)
{
	if (ipCameraObj == NULL)
	{
		//udi_erro_log("%s:ipCameraObj is NULL !\n", __FUNCTION__);
		return 0;
	}

	CameraInfo *pCameraInfo = (CameraInfo *)ipCameraObj;
	if (pCameraInfo->is_start == 1 && pCameraInfo->iTcpSock > 0)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}


//for debug
void* ip_camera_init_default_main(const IPCameraRecvCallBackFunc callBack, void* context)
{
	return ip_camera_init_real(DEFAULT_MAIN_IP, DEFAULT_MAIN_PORT, DEFAULT_MAIN_URL, DEFAULT_MAIN_USER, DEFAULT_MAIN_PASSWD, callBack, context, 0);
}

void* ip_camera_init_default_sub(const IPCameraRecvCallBackFunc callBack, void* context)
{
	return ip_camera_init_real(DEFAULT_SUB_IP, DEFAULT_SUB_PORT, DEFAULT_SUB_URL, DEFAULT_SUB_USER, DEFAULT_SUB_PASSWD, callBack, context, 1);
}

